package inventory.utils;

import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 适合本项目的查询条件集生成器
 * @author sxt
 * @create 2019-11-09 12:52
 */
public class SelectingMapGenerator<T>{

    private String GET_METHOD_PREFIX = "get";
    private String SET_METHOD_PREFIX = "set";

    private Class<T> targetPoClass;

    private SelectingCondition selectingCondition;

    private Map<String,Object> resultQueryConditionMap;

    private Map<String, Method> setMethodsForTargetPoClass;

    private Map<String, Method> getMethodsForSelectingCondition;

    public SelectingMapGenerator() {
    }

    /**
     * 初始化查询条件集生成器
     * @param targetPoClass
     * @param selectingCondition
     */
    public SelectingMapGenerator(Class<T> targetPoClass, SelectingCondition selectingCondition) {
        this.targetPoClass = targetPoClass;
        this.selectingCondition = selectingCondition;
        this.getMethodsForSelectingCondition = this.getGetMethod((Class<T>) selectingCondition.getClass());
        this.setMethodsForTargetPoClass = this.getSetMethod(targetPoClass);
    }

    /*
     * 得到类中的get方法
     */
    private Map<String, Method> getGetMethod(Class<T> targetPoClass){
        Method[] tmp= targetPoClass.getMethods();
        Map<String,Method> methods = new HashMap<>();
        for(int i = 0; i < tmp.length; i++){
            Method method = tmp[i];
            if(method.getName().startsWith(GET_METHOD_PREFIX)){
                methods.put(method.getName(),method);
            }
        }
        return methods;
    }

    /*
     * 得到类中的set方法
     */
    private Map<String, Method> getSetMethod(Class<T> targetPoClass){
        Method[] tmp= targetPoClass.getMethods();
        Map<String,Method> methods = new HashMap<>();
        for(int i = 0; i < tmp.length; i++){
            Method method = tmp[i];
            if(method.getName().startsWith(SET_METHOD_PREFIX)){
                methods.put(method.getName(),method);
            }
        }
        return methods;
    }



    public Map getResultQueryConditionMap(){
        resultQueryConditionMap = new HashMap<>();

        Field[] declaredFields = targetPoClass.getDeclaredFields();
        for (Field field : declaredFields) {
            CName annotation = field.getAnnotation(CName.class);
            if (annotation != null) {
                String value = annotation.value();
//                System.out.println(value);
                String key = UnderlineWithHump.HumpToUnderline(field.getName());
                String methodName = GET_METHOD_PREFIX + value.substring(0,1).toUpperCase() + value.substring(1);
                Method method = getMethodsForSelectingCondition.get(methodName);
                Object rs = null;
                try {
                    rs = method.invoke(selectingCondition);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
                if(!StringUtils.isEmpty(rs))
                    resultQueryConditionMap.put(key,rs);

            }else {

                String filedName = field.getName();
                String key = UnderlineWithHump.HumpToUnderline(filedName);
                String methodName = GET_METHOD_PREFIX + filedName.substring(0,1).toUpperCase() + filedName.substring(1);
                Method method = getMethodsForSelectingCondition.get(methodName);
                if(method != null){
                    Object rs = null;
                    try {
                        rs = method.invoke(selectingCondition);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                    if(!StringUtils.isEmpty(rs))
                        resultQueryConditionMap.put(key,rs);
                }

            }




        }


//        Set<String> strings = resultQueryConditionMap.keySet();
//        for (String s:strings) {
//            Object o = resultQueryConditionMap.get(s);
//            System.out.println(s+" "+o);
//        }


        return resultQueryConditionMap;
    }










}
